home *** CD-ROM | disk | FTP | other *** search
/ Czech Logic, Card & Gambling Games / Logické hry.iso / hry / Sokoban / source / lang.cpp next >
C/C++ Source or Header  |  2006-03-15  |  7KB  |  282 lines

  1. //---------------------------------------------------------------------------
  2. #include <windows.h>
  3. #include "lang.h"
  4. /*
  5. Pou₧itφ:
  6. naΦφst lang z registru, potom zavolat initLang() a langChanded()
  7. do WM_COMMAND dßt setLang(cmd)
  8. do WM_INITDIALOG dßt setDlgTexts(hDlg,titleId)
  9. vytvo°it langChanged() - menu, file filters, invalidate, nemodßlnφ dialogy
  10. */
  11.  
  12. #ifndef MAXLNGSTR
  13.  #define MAXLNGSTR 1500
  14. #endif
  15. //---------------------------------------------------------------------------
  16. const int MAXLANG=60;
  17. char lang[64];         //nßzev jazyka
  18. char *langFile;        //obsah souboru (mφsto \n jsou \0)
  19. char *lngstr[MAXLNGSTR];    //ukazatele na °ßdky v langFile
  20. char *lngNames[MAXLANG+1];   //nßzvy vÜech jazyk∙
  21. //-------------------------------------------------------------------------
  22. #define sizeA(A) (sizeof(A)/sizeof(*A))
  23.  
  24. char *lng(int i, char *s)
  25. {
  26.  return (i>=0 && i<sizeA(lngstr) && lngstr[i]) ? lngstr[i] : s;
  27. }
  28.  
  29. //o°φzne cestu
  30. char *cutPath(char *s)
  31. {
  32.  char *t;
  33.  t=strchr(s,0);
  34.  while(t>=s && *t!='\\') t--;
  35.  t++;
  36.  return t;
  37. }
  38.  
  39. //na fn zapφÜe pracovnφ adresß° a p°idß k n∞mu soubor e
  40. void getExeDir(char *fn, char *e)
  41. {
  42.  GetModuleFileName(0,fn,192);
  43.  strcpy(cutPath(fn), e);
  44. }
  45. //-------------------------------------------------------------------------
  46. static BOOL CALLBACK enumControls(HWND hwnd, LPARAM)
  47. {
  48.  int i=GetDlgCtrlID(hwnd);
  49.  if((i>=300 && i<sizeA(lngstr) || i<11 && i>0) && lngstr[i]){
  50.    SetWindowText(hwnd,lngstr[i]);
  51.  }
  52.  return TRUE;
  53. }
  54.  
  55. void setDlgTexts(HWND hDlg)
  56. {
  57.  EnumChildWindows(hDlg,(WNDENUMPROC)enumControls,0);
  58. }
  59.  
  60. void setDlgTexts(HWND hDlg, int id)
  61. {
  62.  char *s=lng(id,0);
  63.  if(s) SetWindowText(hDlg,s);
  64.  setDlgTexts(hDlg);
  65. }
  66.  
  67. //znovu naΦti nemodßlnφ dialog nebo vytvo° nov² dialog na pozici x,y
  68. void changeDialog(HWND &wnd, int x,int y,LPCTSTR dlgTempl, DLGPROC dlgProc)
  69. {
  70.  HWND a,w;
  71.  
  72.  a=GetActiveWindow();
  73.  w=CreateDialog(inst,dlgTempl,0,dlgProc);
  74.  if(wnd){
  75.    RECT rc;
  76.    GetWindowRect(wnd,&rc);
  77.    MoveWindow(w,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,FALSE);
  78.    if(IsWindowVisible(wnd)) ShowWindow(w,SW_SHOW);
  79.    DestroyWindow(wnd);
  80.  }else{
  81.    SetWindowPos(w,0,x,y,0,0,SWP_NOZORDER|SWP_NOSIZE);
  82.  }
  83.  wnd=w;
  84.  if(a) SetActiveWindow(a);
  85. }
  86. //-------------------------------------------------------------------------
  87. static int *subPtr;
  88.  
  89. //rekurzivn∞ projde menu a zm∞nφ nßzvy
  90. static void fillPopup(HMENU h)
  91. {
  92.  int i,id,j;
  93.  char *s;
  94.  HMENU sub;
  95.  MENUITEMINFO mii;
  96.  
  97.  for(i=GetMenuItemCount(h)-1; i>=0; i--){
  98.    id=GetMenuItemID(h,i);
  99.    if(id==29999){
  100.      for(j=0; lngNames[j]; j++){
  101.        InsertMenu(h,0xFFFFFFFF,
  102.          MF_BYPOSITION|(_stricmp(lngNames[j],lang)?0:MF_CHECKED),
  103.          30000+j,lngNames[j]);
  104.      }
  105.      DeleteMenu(h,0,MF_BYPOSITION);
  106.    }else{
  107.      if(id<0 || id>=0xffffffff){
  108.        sub=GetSubMenu(h,i);
  109.        if(sub){
  110.          id=*subPtr++;
  111.          fillPopup(sub);
  112.        }
  113.      }
  114.      s=lng(id,0);
  115.      if(s){
  116.        mii.cbSize=sizeof(MENUITEMINFO);
  117.        mii.fMask=MIIM_TYPE|MIIM_STATE;
  118.        mii.fType=MFT_STRING;
  119.        mii.fState=MFS_ENABLED;
  120.        mii.dwTypeData=s;
  121.        mii.cch= (UINT) strlen(s);
  122.        SetMenuItemInfo(h,i,TRUE,&mii);
  123.      }
  124.    }
  125.  }
  126. }
  127.  
  128. //naΦte menu z resource name
  129. //subId jsou Φφsla °et∞zc∙ pro submenu
  130. HMENU loadMenu(char *name, int *subId)
  131. {
  132.  HMENU hMenu= LoadMenu(inst,name);
  133.  subPtr=subId;
  134.  fillPopup(hMenu);
  135.  return hMenu;
  136. }
  137.  
  138. void loadMenu(HWND hwnd, char *name, int *subId)
  139. {
  140.  if(!hwnd) return;
  141.  HMENU m= GetMenu(hwnd);
  142.  SetMenu(hwnd,loadMenu(name,subId));
  143.  DestroyMenu(m);
  144. }
  145. //-------------------------------------------------------------------------
  146. static void parseLng()
  147. {
  148.  char *s,*d,*e;
  149.  int id,err=0,line=1;
  150.  
  151.  for(s=langFile; *s; s++){
  152.    if(*s==';' || *s=='#' || *s=='\n' || *s=='\r'){
  153.      //komentß°
  154.    }else{
  155.      id=(int)strtol(s,&e,10);
  156.      if(s==e){
  157.        if(!err) msg(lng(755,"Error in %s\nLine %d"),lang,line);
  158.        err++;
  159.      }else if(id<0 || id>=sizeA(lngstr)){
  160.        if(!err) msg(lng(756,"Error in %s\nMessage number %d is too big"),lang,id);
  161.        err++;
  162.      }else if(lngstr[id]){
  163.        if(!err) msg(lng(757,"Error in %s\nDuplicated number %d"),lang,id);
  164.        err++;
  165.      }else{
  166.        s=e;
  167.        while(*s==' ' || *s=='\t') s++;
  168.        if(*s=='=') s++;
  169.        lngstr[id]=s;
  170.      }
  171.    }
  172.    for(d=s; *s!='\n' && *s!='\r'; s++){
  173.      if(*s=='\\'){
  174.        s++;
  175.        if(*s=='\r'){
  176.          line++;
  177.          if(s[1]=='\n') s++;
  178.          continue;
  179.        }else if(*s=='\n'){
  180.          line++;
  181.          continue;
  182.        }else if(*s=='0'){
  183.          *s='\0';
  184.        }else if(*s=='n'){
  185.          *s='\n';
  186.        }else if(*s=='r'){
  187.          *s='\r';
  188.        }else if(*s=='t'){
  189.          *s='\t';
  190.        }
  191.      }
  192.      *d++=*s;
  193.    }
  194.    if(*s!='\r' || s[1]!='\n') line++;
  195.    *d='\0';
  196.  }
  197. }
  198. //-------------------------------------------------------------------------
  199. void scanLangDir()
  200. {
  201.  int n;
  202.  HANDLE h;
  203.  WIN32_FIND_DATA fd;
  204.  char buf[256];
  205.  
  206.  lngNames[0]="English";
  207.  getExeDir(buf,"language\\*.lng");
  208.  h = FindFirstFile(buf,&fd);
  209.  if(h!=INVALID_HANDLE_VALUE){
  210.   n=1;
  211.   do{
  212.    if(!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
  213.      int len= (int) strlen(fd.cFileName)-4;
  214.      if(len>0){
  215.        char *s= new char[len+1];
  216.        memcpy(s,fd.cFileName,len);
  217.        s[len]='\0';
  218.        lngNames[n++]=s;
  219.      }
  220.    }
  221.   }while(FindNextFile(h,&fd) && n<MAXLANG);
  222.   FindClose(h);
  223.  }
  224. }
  225. //-------------------------------------------------------------------------
  226. static void loadLang()
  227. {
  228.  memset(lngstr,0,sizeof(lngstr));
  229.  char buf[256];
  230.  GetModuleFileName(0,buf,sizeof(buf)-strlen(lang)-14);
  231.  strcpy(cutPath(buf), "language\\");
  232.  char *fn=strchr(buf,0);
  233.  strcpy(fn,lang);
  234.  strcat(buf,".lng");
  235.  HANDLE f=CreateFile(buf,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
  236.  if(f!=INVALID_HANDLE_VALUE){
  237.    DWORD len=GetFileSize(f,0);
  238.    if(len>10000000){
  239.      msg(lng(753,"File %s is too long"),fn);
  240.    }else{
  241.      delete[] langFile;
  242.      langFile= new char[len+3];
  243.      DWORD r;
  244.      ReadFile(f,langFile,len,&r,0);
  245.      if(r<len){
  246.        msg(lng(754,"Error reading file %s"),fn);
  247.      }else{
  248.        langFile[len]='\n';
  249.        langFile[len+1]='\n';
  250.        langFile[len+2]='\0';
  251.        parseLng();
  252.      }
  253.    }
  254.    CloseHandle(f);
  255.  }
  256. }
  257. //---------------------------------------------------------------------------
  258. int setLang(int cmd)
  259. {
  260.  if(cmd>=30000 && cmd<30000+MAXLANG && lngNames[cmd-30000]){
  261.    strcpy(lang,lngNames[cmd-30000]);
  262.    loadLang();
  263.    langChanged();
  264.    return 1;
  265.  }
  266.  return 0;
  267. }
  268. //---------------------------------------------------------------------------
  269. void initLang()
  270. {
  271.  scanLangDir();
  272.  if(!lang[0]){
  273.    //autodetekce jazyka
  274.    strcpy(lang,"English");
  275.    LANGID id= GetUserDefaultLangID();
  276.    if(id==0x405) strcpy(lang,"╚esky");
  277.  }
  278.  loadLang();
  279. }
  280. //---------------------------------------------------------------------------
  281.  
  282.